package com.lwj.service;

import com.lwj.aop.PermissionAspect;
import com.lwj.exception.BusinessException;
import com.lwj.vo.configuration.UserInfo;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 * @author LemonZuo
 * @create 2020-04-28 22:17
 */
@Component
public class SpringUtil implements ApplicationContextAware {
    private static ApplicationContext context;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        context = applicationContext;
    }

    public static void set(ApplicationContext applicationContext) {
        context = applicationContext;
    }

    /**
     * 通过字节码获取
     * @param beanClass
     * @param <T>
     * @return
     */
    public static <T> T getBean(Class<T> beanClass) {
        return context.getBean(beanClass);
    }

    /**
     * 通过BeanName获取
     * @param beanName
     * @param <T>
     * @return
     */
    public static <T> T getBean(String beanName) {
        return (T) context.getBean(beanName);
    }

    /**
     * 通过beanName和字节码获取
     * @param name
     * @param beanClass
     * @param <T>
     * @return
     */
    public static <T> T getBean(String name, Class<T> beanClass) {
        return context.getBean(name, beanClass);
    }
    /**
     * 取得当前请求的HttpServletRequest.
     *
     * @return HttpServletRequest
     */
    public static final HttpServletRequest getRequest() {
        return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
    }

    public static final ServletContext getServletContext(){
        return getRequest().getServletContext();
    }

    /**
     * 取得当前请求的HttpServletResponse.
     *
     * @return HttpServletResponse
     */
    public static final HttpServletResponse getResponse() {
        return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
    }

    /**
     * 取得当前请求的Session.
     *
     * @return HttpSession
     */
    public static final HttpSession getSession() {
        return getRequest().getSession();
    }

    /**
     * 取得当前请求的HTTP协议首行内容.
     * <p>
     * 并非实际客户端发来的首行，而是从请求上下文中取出HTTP<code>METHOD+URI+PROTOCOL</code>拼接模拟出来的。
     *
     * @return 方法+空格+URI+空格+协议版本
     */
    public static final String getHttpFirstLine() {
        HttpServletRequest req = getRequest();
        return String.format("%s %s %s", req.getMethod(), req.getRequestURI(), req.getProtocol());
    }

    /**
     * 尝试获取当前请求的真实客户端地址.
     *
     * @return 默认从<code>request.getRemoteAddr()</code>，也会尝试从一些常见HTTP Header中识别
     */
    public static String getRealRemoteAddr() {
        return determineRemoteIp(getRequest(), true);
    }

    /**
     * 从当前HTTP请求中识别客户端IP地址。相对于服务端来说，“远程地址”就是指客户端的地址。
     * <p>
     * 除了访问CGI基本属性REMOTE_ADDR，还可能会根据HTTP Header中的特殊属性来识别客户端的“真实”地址。
     *
     * @param request HTTP请求上下文
     * @param tryHeaders 不仅仅只获取远程地址，也尝试从Header中查找常见转发、代理会使用的客户端IP标识
     * @return 客户端地址。如果没有传入request则直接返回UNK
     */
    public static String determineRemoteIp(HttpServletRequest request, boolean tryHeaders) {
        if (request == null) {
            return "UNK";
        }
        String clientIp = request.getRemoteAddr();
        if (tryHeaders && StringUtils.hasText(request.getHeader("X-Real-IP"))) {
            clientIp = request.getHeader("X-Real-IP");
        }
        return clientIp;
    }

    /**
     * 强制令响应成为no cache方式的方便方法.
     * <p>
     * 其实就是向<code>HttpServletResponse</code>中添加Pragma、Cache-Control、Expires这几个Header。
     */
    public static void forceResponseNoCache() {
        HttpServletResponse response = getResponse();
        response.setHeader("Pragma", "no-cache");
        response.setHeader("Cache-Control", "no-cache,no-store,max-age=0");
        response.setDateHeader("Expires", 0);
    }

    public static String getUserId() {
        UserInfo user = getUser();
        return user == null ? null : user.getEmpId();
    }

    public static String getUserName() {
        UserInfo user = getUser();
        return user == null ? "" : user.getName();
    }

    public static UserInfo getUser() {
        Object o = getSession().getAttribute("currentUser");
        if (o == null)
            return null;
        return (UserInfo) o;
    }
    public static String getDepartmentRoleId(){
        HttpServletRequest request = getRequest();
        String header = request.getHeader("departmentRoleId");
        if(!StringUtils.hasText(header)){
            header=request.getParameter("departmentRoleId");
        }
        if(!StringUtils.hasText(header)){
            throw new BusinessException("请选择角色");
        }
        return header;
    }

    public static String getPermissionCode(){
        HttpServletRequest request = getRequest();
        String header = request.getHeader("permissionCode");
        if(!StringUtils.hasText(header)){
            header=request.getParameter("permissionCode");
        }
        return header;
    }
    public static String codeInAttribute(){
        HttpServletRequest request = getRequest();
        String permissionCode = (String) request.getAttribute(PermissionAspect.PERMISSION_CODE);
        return permissionCode;
    }
}
